/**
 * @author xsg
 * @author zh
 * @author zyh
 */

//函数名称带O表示优化
//使用了全局变量---计数器和材质

function createMultiLineString(geomData, group, material){//geomData表示对应一个geojson文件的所有某种geometry类型的数据
    if(geomData.length == 0)
        return;

    for (var j_L1 in geomData) {
        //console.log("在此文件之中，一个geometry的顶点坐标数据：");
        for (var j_L2 in geomData[j_L1]) {
            var vertices = geomData[j_L1][j_L2];//---Array---one linestring
            // one polygon -- one linestrip
            var geoLine = new THREE.BufferGeometry();
            geoLine.addAttribute( 'position', new THREE.Float32BufferAttribute(vertices, 3));
            var line = new THREE.Line( geoLine, material );
            group.add( line );
        }
    }
}
function createMultiLineStringO(geomData, group, material){//geomData表示对应一个geojson文件的所有某种geometry类型的数据
    if(geomData.length == 0)
        return;

    var geom = new THREE.BufferGeometry();
    var as   = new Array();
    for (var j_L1 in geomData) {
        //console.log("在此文件之中，一个geometry的顶点坐标数据：");
        for (var j_L2 in geomData[j_L1]) {
            var vertices = geomData[j_L1][j_L2];//---Array---one linestring
            // one polygon -- one linestrip
            var geoLine = new THREE.BufferGeometry();
            geoLine.addAttribute( 'position', new THREE.Float32BufferAttribute(vertices, 3));
            as.push(geoLine);
        }
    }
    var rv = THREE.BufferGeometryUtils.mergeBufferGeometries(as);
    var line = new THREE.LineSegments( rv, material );
    group.add( line );
}
//type含义：0--不需要边框，1--需要边框, 2--需要创建独立的节点当容器
function createMultiPolygon(geomData, group, material, type){//geomData表示对应一个geojson文件的所有某种geometry类型的数据
    if(geomData.length == 0)
        return;

    var bCreateMat = material;

    var vecA        = new THREE.Vector3();
    var vecB        = new THREE.Vector3();
    var normalAB    = new THREE.Vector3();
    var r, alhpa, beta;
    var matBeta  = new THREE.Matrix4();
    var matAlhpa = new THREE.Matrix4();
    var needProcessed = false;

    var bigFloor;
    if(type == 2)
        bigFloor = new THREE.Group();

    for (var j_L1 in geomData) {
        //console.log("在此文件之中，一个geometry的顶点坐标数据：");
        var geometry    = new THREE.BufferGeometry();
        var indices     = new Array();
        var normals     = new Array();
        var verticesS   = new Array();//文件中一个geometry的顶点数据
        var vIndexSum   = 0;

        for (var j_L2 in geomData[j_L1][1]) {
            if (j_L2 == 0 && bCreateMat==undefined){
                continue;
            }
            var vertices = geomData[j_L1][1][j_L2];//---Array---one polygon

            vecA.set(vertices[0] - vertices[6], vertices[1] - vertices[7], vertices[2] - vertices[8]);
            vecB.set(vertices[3] - vertices[6], vertices[4] - vertices[7], vertices[5] - vertices[8]);
            normalAB = vecA.cross(vecB);
            normalAB.normalize();
            needProcessed = false;
            if(normalAB.x != 0 || normalAB.y != 0)//仅平行于xy平面的不需处理
            {
                r = Math.sqrt(normalAB.x*normalAB.x + normalAB.z*normalAB.z);
                alhpa = Math.atan2(normalAB.y, r);
                beta  = Math.atan2(normalAB.x, normalAB.z);
                matBeta.makeRotationY(-beta);
                matAlhpa.makeRotationX(alhpa);
                matAlhpa.multiply(matBeta);
                //normalAB.applyMatrix4(matAlhpa);
                // console.log("result: " + normalAB.x + "  " + normalAB.y);
                needProcessed = true;
            }

            var forTri = new Array();
            for (var key = 0; key<vertices.length/3; key++) {
                forTri.push(new THREE.Vector3(vertices[key*3+0], vertices[key*3+1], vertices[key*3+2]));
                if(needProcessed)
                    forTri[key].applyMatrix4(matAlhpa);
            }

            var triangles = THREE.ShapeUtils.triangulateShape(forTri, []);
            for ( var k = 0; k < triangles.length; k++ ) {
                if(normalAB.z != 0){
                    indices.push(vIndexSum  + triangles[k][0]) ;
                    indices.push(vIndexSum  + triangles[k][1]) ;
                    indices.push(vIndexSum  + triangles[k][2]) ;
                } else {
                    indices.push(vIndexSum  + triangles[k][2]) ;
                    indices.push(vIndexSum  + triangles[k][1]) ;
                    indices.push(vIndexSum  + triangles[k][0]) ;
                }
            }

            for (var key = 0; key<vertices.length/3; key++) {
                if(normalAB.z < 0)
                    normals.push(-normalAB.x, -normalAB.y, -normalAB.z);
                else
                    normals.push(normalAB.x, normalAB.y, normalAB.z);
            }

            verticesS.push.apply(verticesS, vertices);
            vIndexSum   += vertices.length/3;
        }
        geometry.setIndex(new THREE.Uint32BufferAttribute(indices, 1));
        geometry.addAttribute( 'position', new THREE.Float32BufferAttribute(verticesS, 3));
        geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute(normals, 3));
        geometry.computeBoundingSphere();


        if(bCreateMat == undefined){
            material = new THREE.MeshPhongMaterial({color:0xffffff,
                transparent:true,
                opacity:0.3});
        }
        var mesh, edges, line;
        if(0 == type)
        {
            mesh = new THREE.Mesh( geometry, material);
            mesh.renderOrder = 0;
            group.add(mesh);
        }else if(1 == type){
            mesh = new THREE.Mesh( geometry, material);
            mesh.renderOrder = 1;
            group.add(mesh);

            edges = new THREE.EdgesGeometry( geometry );
            line = new THREE.LineSegments( edges, g_frameMat);
            line.renderOrder = 1;
            g_frameMPolygons.add(line);
        }else if(type == 2){
            mesh = new THREE.Mesh( geometry, material);
            bigFloor.add(mesh);
        }
        mesh.name = geomData[j_L1][0].toString();
        if(line != undefined)
            line.name = geomData[j_L1][0].toString();
    }

    if( type == 2)
        group.add(bigFloor);

}
function createMultiPolygonO(geomData, group, material, visible, eid){//geomData表示对应一个geojson文件的所有某种geometry类型的数据
    if(geomData.length == 0)
        return;

    var geometry    = new THREE.BufferGeometry();
    var indices     = new Array();
    var normals     = new Array();
    var verticesS   = new Array();//文件中所有geometry的顶点数据
    var vIndexSum   = 0;

    var vecA        = new THREE.Vector3();
    var vecB        = new THREE.Vector3();
    var normalAB    = new THREE.Vector3();
    var r, alhpa, beta;
    var matBeta  = new THREE.Matrix4();
    var matAlhpa = new THREE.Matrix4();
    var needProcessed = false;

    for (var j_L1 in geomData) {
        //console.log("在此文件之中，一个geometry的顶点坐标数据：");
        for (var j_L2 in geomData[j_L1]) {

            

            var vertices = geomData[j_L1][j_L2];//---Array---one polygon

            vecA.set(vertices[0] - vertices[6], vertices[1] - vertices[7], vertices[2] - vertices[8]);
            vecB.set(vertices[3] - vertices[6], vertices[4] - vertices[7], vertices[5] - vertices[8]);
            normalAB = vecA.cross(vecB);
            normalAB.normalize();
            needProcessed = false;

            if(normalAB.x != 0 || normalAB.y != 0)//仅平行于xy平面的不需处理
            {
                r = Math.sqrt(normalAB.x*normalAB.x + normalAB.z*normalAB.z);
                alhpa = Math.atan2(normalAB.y, r);
                beta  = Math.atan2(normalAB.x, normalAB.z);
                matBeta.makeRotationY(-beta);
                matAlhpa.makeRotationX(alhpa);
                matAlhpa.multiply(matBeta);
                //normalAB.applyMatrix4(matAlhpa);
                //console.log("result: " + normalAB.x + "  " + normalAB.y);
                needProcessed = true;
            }

            var forTri = new Array();
            for (var key = 0; key<vertices.length/3; key++) {
                forTri.push(new THREE.Vector3(vertices[key*3+0], vertices[key*3+1], vertices[key*3+2]));
                if(needProcessed)
                    forTri[key].applyMatrix4(matAlhpa);
            }
            var triangles = THREE.ShapeUtils.triangulateShape(forTri, []);
            for ( var k = 0; k < triangles.length; k++ ) {
                if(normalAB.z != 0){
                    indices.push(vIndexSum  + triangles[k][0]) ;
                    indices.push(vIndexSum  + triangles[k][1]) ;
                    indices.push(vIndexSum  + triangles[k][2]) ;
                } else {
                    indices.push(vIndexSum  + triangles[k][2]) ;
                    indices.push(vIndexSum  + triangles[k][1]) ;
                    indices.push(vIndexSum  + triangles[k][0]) ;
                }
            }

            for (var key = 0; key<vertices.length/3; key++) {
                if(normalAB.z < 0)
                    normals.push(-normalAB.x, -normalAB.y, -normalAB.z);
                else
                    normals.push(normalAB.x, normalAB.y, normalAB.z);
            }

            verticesS.push.apply(verticesS, vertices);
            vIndexSum   += vertices.length/3;
        }
    }
    geometry.setIndex(new THREE.Uint32BufferAttribute(indices, 1));
    geometry.addAttribute( 'position', new THREE.Float32BufferAttribute(verticesS, 3));
    geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute(normals, 3));
    geometry.computeBoundingSphere();

    var mesh = new THREE.Mesh( geometry, material);
    mesh.visible = false;
    group.add(mesh);

    if(visible)
        mesh.visible = true;

    if(eid != undefined && eid > 0)
        mesh.name = eid;
}